package com.chu.cloud.zuul.filter.pre;

import com.chu.cloud.response.ResultVo;
import com.chu.cloud.util.JsonUtils;
import com.chu.cloud.zuul.properties.MicroserviceProxyRoute;
import com.chu.cloud.zuul.properties.RequestPermitProperties;
import com.chu.cloud.zuul.util.IpUtil;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 进入微服务许可过滤器,过滤需要鉴权的API,以及黑白名单过滤
 *
 * @author: Tianshu.CHU
 * @Date: 2018/6/12 20:33
 * @Description:
 */
@Slf4j
public class AccessPermitFilter extends ZuulFilter {


    @Autowired
    private RequestPermitProperties permitProperties;

    @Autowired
    private MicroserviceProxyRoute serviceProxyRoute;

    private final PathMatcher pathmatcher = new AntPathMatcher();

    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return -1;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext rc = RequestContext.getCurrentContext();
        HttpServletRequest request = rc.getRequest();
        String uri = request.getRequestURI();
        boolean shouldFilter = !uri.contains("swagger") && !uri.contains("api-docs")
                && uri.startsWith(serviceProxyRoute.getOpenService());
        boolean b = rc.get("isProcess") == null || Boolean.parseBoolean(rc.get("isProcess").toString());
        return shouldFilter && b;
    }

    @Override
    public Object run() {
        RequestContext requestContext = RequestContext.getCurrentContext();
        final HttpServletRequest request = requestContext.getRequest();
        final HttpServletResponse response = requestContext.getResponse();
        response.setContentType("application/json;charset=utf-8");
        String ip = IpUtil.getIp(request);
        boolean isPermit = permitProperties.getBlackList().stream().anyMatch(permit -> pathmatcher.match(permit, ip));
        if (isPermit){
            requestContext.setResponseBody(JsonUtils.obj2json(ResultVo.errorOfMessage("非法用户!")));
            requestContext.set("isProcess",false);
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(HttpStatus.FORBIDDEN.value());
        }

        String uri = request.getRequestURI().replace(serviceProxyRoute.getOpenService(), "");
        log.info("请求uri:{}进入API鉴权 run方法", uri);
        List<String> authApiList = permitProperties.getAuthApi();
        boolean isMatch = authApiList.stream().anyMatch(authUri -> pathmatcher.matchStart(authUri, uri));
        if (isMatch){
            String token = request.getHeader("token");
            if (StringUtils.isEmpty(token)) {
                ResultVo<Object> result = ResultVo.errorOfMessage("token不正确!");
                requestContext.setResponseBody(JsonUtils.obj2json(result));
                requestContext.setSendZuulResponse(false);
                requestContext.set("isProcess", false);
                requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
            }
        }
        return null;
    }


}
